home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 9 / af009.adf / Dave Jones' Locker / MoveShip.S < prev    next >
Text File  |  1987-08-27  |  30KB  |  1,039 lines

  1. *****************************************************************************
  2. *                                            *
  3. *    Amiga system takeover framework                            *
  4. *    1988 Dave Jones, DMA Design                            *
  5. *                                            *
  6. * Allows killing of system, allowing changing of all display & blitter        *
  7. * hardware, restoring to normal after exiting.                        *
  8. * Memory must still be properly allocated/deallocated upon entry/exit       *
  9. * DOS routines for loading must be called BEFORE killing the system           *
  10. *                                            *
  11. * Written using Devpac2                                    *
  12. *                                            *
  13. *****************************************************************************
  14.  
  15.     section    Framework,code_c    
  16.  
  17. *****************************************************************************
  18. * Conditional Code (as last month) to make source code compatible with 
  19. * Argonaut`s ArgAsm. If you have a meg, this code may have to be assembled
  20. * using the CLI-based version of the Arg assembler, due to memory constraints
  21. *                            - Jason H
  22. *****************************************************************************
  23.  
  24.     ifd    __ArgAsm
  25.  
  26.     incdir    "include:"
  27.     include     exec/funcdef.i
  28. _SysBase    equ    $04
  29.  
  30.     elseif
  31.  
  32.     incdir    "include/"
  33.  
  34.     endc
  35.  
  36. * End of conditional block
  37.  
  38.  
  39.     include     libraries/dos_lib.i
  40.     include     exec/exec_lib.i
  41.     include     hardware/custom.i
  42.  
  43. Hardware        equ    $dff000
  44. SystemCopper1        equ    $26
  45. SystemCopper2        equ    $32
  46. PortA            equ    $bfe001
  47. ICRA            equ    $bfed01
  48. LeftMouse        equ    6
  49.  
  50. BackgroundWidth        equ    100    100 bytes wide
  51. ForegroundWidth        equ    92    92  bytes wide
  52. ScreenHeight        equ    192    playing area 192 lines high (12 blocks)
  53. NumberPlanes        equ    3    3 planes in each playfield
  54.  
  55. BytesPerBackPlane    equ    BackgroundWidth*ScreenHeight
  56. BytesPerForePlane    equ    ForegroundWidth*ScreenHeight
  57. BackgroundMemory    equ    2*NumberPlanes*BytesPerBackPlane
  58. ForegroundMemory    equ    NumberPlanes*BytesPerForePlane
  59. MemNeeded        equ    BackgroundMemory+ForegroundMemory
  60.  
  61. FullFirepower        equ    1
  62.  
  63. *******************************************************************************
  64.  
  65. start    lea    GraphicsName(pc),a1    open the graphics library purely
  66.     move.l    _SysBase,a6        to find the system copper
  67.     clr.l    d0
  68.     jsr    _LVOOpenLibrary(a6)
  69.     move.l    d0,GraphicsBase
  70.     lea    DOSName(pc),a1        open the DOS library to allow
  71.     clr.l    d0            the loading of data before
  72.     jsr    _LVOOpenLibrary(a6)    killing the system
  73.     move.l    d0,DOSBase
  74.  
  75.     move.l    #MemNeeded,d0        properly allocate some chip
  76.     moveq.l    #2,d1            memory for screens etc.
  77.     jsr    _LVOAllocMem(a6)    d1 = 2, specifies chip memory
  78.     tst.l    d0            where screens,samples etc
  79.     beq    MemError        must be (bottom 512K)
  80.     move.l    d0,MemBase
  81.  
  82. *******************************************************************************
  83.  
  84.     lea    variables(pc),a5    a5 is the variables pointer
  85.     lea    rasters(a5),a0
  86.     lea    displayraster(a5),a1
  87.     move.l    d0,(a0)+        calculate the address of each plane
  88.     move.l    d0,(a1)+        store them in the variables area,
  89.     add.l    #BytesPerBackPlane,d0    twice for the background as it is
  90.     move.l    d0,(a0)+        double buffered            
  91.     move.l    d0,(a1)+
  92.     add.l    #BytesPerBackPlane,d0
  93.     move.l    d0,(a0)+            
  94.     move.l    d0,(a1)+
  95.     add.l    #BytesPerBackPlane,d0
  96.     move.l    d0,(a0)+            
  97.     add.l    #BytesPerForePlane,d0
  98.     move.l    d0,(a0)+            
  99.     add.l    #BytesPerForePlane,d0
  100.     move.l    d0,(a0)+            
  101.     add.l    #BytesPerForePlane,d0
  102.     move.l    d0,(a0)+            
  103.     move.l    d0,(a1)+
  104.     add.l    #BytesPerBackPlane,d0
  105.     move.l    d0,(a0)+            
  106.     move.l    d0,(a1)+
  107.     add.l    #BytesPerBackPlane,d0
  108.     move.l    d0,(a0)+            
  109.     move.l    d0,(a1)+
  110.  
  111.     move.l    #Hardware,a6
  112.     jsr    TakeSystem
  113.  
  114. *******************************************************************************
  115.  
  116.     move.l    #$dff000,a6        a6 ALWAYS point to base of
  117.     move.l    #-1,bltafwm(a6)        custom chips
  118.     bsr    GameInit
  119.     move.l    #clist,cop1lc(a6)
  120.     move.w    #$87e0,dmacon(a6)    enable copper,sprite,blitter
  121.     move.w    #$7fff,intreq(a6)    clear all int request flags
  122.  
  123. *******************************************************************************
  124.  
  125. * Main game loop with the routines we are yet to cover commented out
  126.  
  127. *******************************************************************************
  128.  
  129. vloop    bsr    waitline223        interrupt set at vertical 
  130.     not.b    vcount(a5)        position 223 (panel start)
  131.     beq    twoblanks        alternate every frame
  132.  
  133.     lea    copperlist(pc),a1    set up registers for routine
  134.     move.w    pf2scroll(a5),d0    checkpf2
  135.     move.w    pf1scroll(a5),d1
  136.     bsr    checkpf2        and branch to it
  137.     bsr    moveship    
  138. *    bsr    check.collision
  139. *    bsr    erase.missiles
  140. *    bsr    levels.code
  141. *    bsr    update.missiles
  142.     bsr    drawfgnds
  143. *    bsr    print.score
  144. *    bsr    check.keys
  145. *    bsr    check.path
  146.     bra    vloop
  147. twoblanks    
  148.     bsr    checkpf1        the following routines are only
  149.     bsr    flipbgnd        executed every second frame
  150.     bsr    moveship
  151. *    bsr    restorebgnds
  152. *    bsr    process.aliens
  153. *    bsr    save.aliens
  154. *    bsr    draw.aliens
  155.  
  156.     btst    #LeftMouse,PortA    lest mouse button to exit
  157.     bne    vloop
  158.     bra    finished    
  159.  
  160. **************************************************************************
  161.  
  162. waitline223
  163.     btst    #4,intreqr+1(a6)    wait for vertical line 223
  164.     beq    waitline223        interrupt set by the
  165.     move.w    #$10,intreq(a6)        copperlist
  166. return    rts
  167.  
  168. **************************************************************************
  169.  
  170. checkpf1
  171.     cmp.w    #3,level.end(a5)    level.end = 3 means 
  172.     beq    return            guardian on, so no scroll
  173.     lea    copperlist(pc),a1
  174.     move.w    pf2scroll(a5),d0    d0 = pf2 scroll value (0-15)
  175.     move.w    pf1scroll(a5),d1    d1 = pf1 scroll value (0-15)
  176.     subq.w    #1,d1            scroll a pixel
  177.     bcs    resetpf1        reset back to 15
  178. checkpf2
  179.     cmp.w    #3,level.end(a5)    as above
  180.     beq    return
  181.     subq.w    #1,d0            scroll a pixel
  182.     bcs    resetpf2        reset to 15 and update pointers
  183. storescroll                    
  184.     move.w    d1,pf1scroll(a5)    resave the values
  185.     move.w    d0,pf2scroll(a5)
  186.     move.w    pf1count(a5),d2
  187.     subq.w    #1,d2            check if at the end of the two
  188.     or.w    d1,d2            screens and flag for the sprite
  189.     move.w    d2,screenend(a5)    routine if true    
  190.     lsl.w    #4,d0
  191.     or.w    d0,d1
  192.     move.w    d1,54(a1)        put the new scroll value into 
  193.     rts                the copper list
  194.  
  195. resetpf1
  196.     moveq    #$f,d1            reset scroll to 15
  197.     subq.w    #1,pf1count(a5)        decrement words scrolled
  198.     bne    storepf1        carry on if not zero
  199.     move.w    #23,pf1count(a5)    otherwise reset the number of
  200.     lea    rasters(a5),a4        words to scroll and reset the 
  201.     lea    displayraster(a5),a3    display planes back to the very
  202.     move.l    (a4)+,(a3)+        start.
  203.     move.l    (a4)+,(a3)+
  204.     move.l    (a4)+,(a3)+        six planes in all
  205.     add.w    #12,a4
  206.     move.l    (a4)+,(a3)+
  207.     move.l    (a4)+,(a3)+
  208.     move.l    (a4)+,(a3)+
  209.     bra    checkpf2        now check pf2
  210. storepf1
  211.     lea    displayraster(a5),a3    increment the plane pointers
  212.     addq.l    #2,(a3)            by a word each
  213.     addq.l    #2,4(a3)        these are background planes
  214.     addq.l    #2,8(a3)        and are therefore double
  215.     addq.l    #2,12(a3)        buffered
  216.     addq.l    #2,16(a3)
  217.     addq.l    #2,20(a3)
  218.     bra    checkpf2
  219.  
  220. resetpf2
  221.     lea    rasters(a5),a4
  222.     moveq    #$f,d0            reset scroll back to 15
  223.     subq.w    #1,pf2count(a5)        decrement the word scroll
  224.     bne    respf2            value and reset if zero
  225.     move.w    #23,pf2count(a5)
  226.     clr.w    pf2offset(a5)        offset is reverse of pf2count
  227.     cmp.w    #1,level.end(a5)    and is used for the copper
  228.     bne    respf2            level.end = 1 when map finished
  229.     addq.w    #1,level.end(a5)    so start to draw guardian
  230. *    bsr    change.colours        setup the guardian colours
  231. *    move.w    #6*72,guard.offset(a5)    changes the missiles
  232. respf2 
  233.     move.l    12(a4),d2        get the foreground plane 
  234.     move.l    16(a4),d3        pointers and add the offset to
  235.     move.l    20(a4),d4        them
  236.     addq.w    #2,pf2offset(a5)
  237.     add.w    pf2offset(a5),d2    store these in the copper list
  238.     add.w    pf2offset(a5),d3
  239.     add.w    pf2offset(a5),d4
  240. storepf2
  241.     move.w    d2,30(a1)
  242.     move.w    d3,38(a1)
  243.     move.w    d4,46(a1)
  244.     bra    storescroll
  245.  
  246. **************************************************************************
  247.  
  248. flipbgnd    
  249.     lea    copperlist(pc),a1    swap the background displays
  250.     lea    displayraster(a5),a3    every second frame
  251.     move.l    (a3),d4
  252.     move.l    4(a3),d5
  253.     move.l    8(a3),d6
  254.     move.l    12(a3),(a3)
  255.     move.l    16(a3),4(a3)
  256.     move.l    20(a3),8(a3)
  257.     move.l    d4,12(a3)
  258.     move.l    d5,16(a3)
  259.     move.l    d6,20(a3)
  260.     addq    #4,d4            add 4 bytes (32 pixels) to the
  261.     addq    #4,d5            pointers so that clipping can
  262.     addq    #4,d6            be carried out on the left
  263.     move.w    d4,6(a1)        hand side
  264.     swap    d4
  265.     move.w    d4,2(a1)        store the new ones in the copper
  266.     move.w    d5,14(a1)        list
  267.     swap    d5
  268.     move.w    d5,10(a1)
  269.     move.w    d6,22(a1)
  270.     swap    d6
  271.     move.w    d6,18(a1)
  272.     not.b    screen.num(a5)
  273.     rts
  274.  
  275. **************************************************************************
  276.  
  277. drawfgnds
  278.     cmp.w    #3,level.end(a5)    3 for guardian fully on
  279.     beq    return
  280.     cmp.w    #2,level.end(a5)    2 for drawing guardian
  281.     beq    return
  282.     tst.w    pf2scroll(a5)        every 16 pixels a new strip
  283.     beq    drawbegin        of foreground graphics are
  284.     cmp.w    #$e,pf2scroll(a5)    drawn into a hidden part
  285.     beq    drawend            of the screen
  286.     rts
  287. drawbegin
  288.     bsr    setupblit
  289.     clr.l    d6            d6 = offset into the screen
  290.     move.l    fgndpointer(a5),a0    for the start of the screen
  291.     bsr    drawfgnd        this will be zero
  292.     subq    #1,a0
  293.     move.l    a0,fgndpointer(a5)
  294.     rts
  295.  
  296. drawend
  297.     bsr    setupblit
  298.     moveq    #46,d6            as the screen is 46 bytes
  299.     move.l    fgndpointer(a5),a0    wide, this is the offset
  300.     cmp.b    #$ff,(a0)        at which to draw the strip
  301.     bne    drawfgnd
  302.     sub.w    #12,a0            the end of map is flagged
  303.     move.l    a0,fgndpointer(a5)    by an FF block number
  304.     move.w    #1,level.end(a5)    flag the end of the map
  305.  
  306. drawfgnd
  307.     clr.l    d0
  308.     move.b    (a0)+,d0        d0 = block number (0-254)
  309.     lea    rasters(a5),a4        get the current foreground
  310.     move.l    12(a4),d1        plane pointers in d1,d2,d3
  311.     move.l    16(a4),d2
  312.     move.l    20(a4),d3
  313.     add.l    d6,d1            add the offset passed
  314.     add.l    d6,d2
  315.     add.l    d6,d3
  316.     add.w    pf2offset(a5),d1    add the scrolled words
  317.     add.w    pf2offset(a5),d2    offset to each plane
  318.     add.w    pf2offset(a5),d3
  319.     moveq    #11,d7            12 blocks in height
  320.     move.l    #graphics,a4        a4 = base address of the graphics
  321. fgndloop                    
  322.     move.l    a4,d4
  323.     mulu    #96,d0            96 bytes per graphic blocks
  324.     ext.l    d0            (2 bytes wide x 16 high
  325.     add.l    d0,d4             x 3 planes)
  326.     bsr    blitfgnd
  327.     add.l    #ForegroundWidth*16,d1    work out address of 16 scanlines
  328.     add.l    #ForegroundWidth*16,d2    down 
  329.     add.l    #ForegroundWidth*16,d3
  330.     clr.l    d0
  331.     move.b    (a0)+,d0        get next block number
  332.     dbf    d7,fgndloop        and repeat for all 12
  333.     rts
  334.  
  335. blitfgnd
  336.     move.l    d1,bltdpt(a6)        blit a 16x16 pixel block
  337.     move.l    d4,bltapt(a6)        into the foreground screen
  338.     move.w    #$0401,bltsize(a6)    unmasked with no shift
  339.     add.l    #32,d4
  340.     move.l    d2,bltdpt(a6)
  341.     move.l    d4,bltapt(a6)
  342.     move.w    #$0401,bltsize(a6)
  343.     add.l    #32,d4
  344.     move.l    d3,bltdpt(a6)
  345.     move.l    d4,bltapt(a6)
  346.     move.w    #$0401,bltsize(a6)
  347.     rts
  348.  
  349. setupblit
  350.     move.w    #$09f0,bltcon0(a6)        minterm for D = A
  351.     clr.w    bltcon1(a6)
  352.     clr.w    bltamod(a6)            data is stored sequentially
  353.     move.w    #ForegroundWidth-2,bltdmod(a6)
  354.     rts
  355.  
  356. **************************************************************************
  357.  
  358. buildbackgnd
  359.     lea    rasters(a5),a0
  360.     move.l    (a0),a1            get the background plane pointers
  361.     move.l    4(a0),a2        in a1-a4 (double buffered so 2 sets)
  362.     move.l    24(a0),a3        background graphics are only 4 colour
  363.     move.l    28(a0),a4        (2 planes) so third plane is ignored
  364.     addq    #4,a1            skip the hidden words used for
  365.     addq    #4,a2            clipping
  366.     addq    #4,a3
  367.     addq    #4,a4
  368.     move.l    #backgroundtable,a0    a0 = the background map
  369.     move.w    level.number(a5),d0
  370.     mulu    #144,d0            144 bytes per background map
  371.     add.w    d0,a0
  372.     moveq    #11,d0            12 blocks high
  373. build1    moveq    #11,d1            24 blocks across
  374.     movem.l    a1-a4,-(sp)
  375. build2    move.b    (a0),d2            this loop draws 2 across
  376.     lsr.b    #4,d2            block number stored in 4 bits
  377.     bsr    drawback
  378.     move.b    (a0)+,d2
  379.     and.b    #$f,d2
  380.     tst.w    d1
  381.     beq    skipit
  382.     bsr    drawback
  383. skipit    dbf    d1,build2        do all 24 across
  384.     movem.l    (sp)+,a1-a4
  385.     add.l    #BackgroundWidth*16,a1    next block down the way
  386.     add.l    #BackgroundWidth*16,a2
  387.     add.l    #BackgroundWidth*16,a3
  388.     add.l    #BackgroundWidth*16,a4
  389.     dbf    d0,build1        do all 12 high
  390.     move.l    #$dff000,a6
  391.     rts
  392.  
  393. drawback
  394.     lea    backgrounds,a6        a6 = the background graphics
  395.     move.w    level.number(a5),d3
  396.     mulu    #1024,d3        1024 bytes per level of background
  397.     add.w    d3,a6            graphics (16 blocks)
  398.     and.w    #$f,d2
  399.     mulu    #64,d2            64 bytes per block
  400.     add.l    d2,a6            (2 bytes x 16 high x 2 planes)
  401.     movem.l    a1-a4,-(sp)
  402.     moveq    #15,d3
  403. drawb1    move.w    (a6),(a1)        draw into both the screens
  404.     move.w    (a6),(a3)
  405.     move.w    (a6),46(a1)        
  406.     move.w    (a6),46(a3)
  407.     move.w    32(a6),(a2)
  408.     move.w    32(a6),(a4)
  409.     move.w    32(a6),46(a4)
  410.     move.w    32(a6),46(a2)
  411.     add.w    #BackgroundWidth,a1
  412.     add.w    #BackgroundWidth,a2
  413.     add.w    #BackgroundWidth,a3
  414.     add.w    #BackgroundWidth,a4
  415.     addq    #2,a6
  416.     dbf    d3,drawb1
  417.     movem.l    (sp)+,a1-a4
  418.     addq    #2,a1            next block along
  419.     addq    #2,a2
  420.     addq    #2,a3
  421.     addq    #2,a4
  422.     rts
  423.  
  424. **************************************************************************
  425.  
  426. GameInit
  427.     lea    map,a0
  428.     move.l    a0,fgndpointer(a5)    set up the map index
  429.     move.w    #23,pf1count(a5)    width of the foreground in words
  430.     move.w    #24,pf2count(a5)    width of the background in words
  431.     move.w    #15,pf1scroll(a5)    initial scroll value
  432.     move.w    #15,pf2scroll(a5)
  433.     move.w    #100,xpos(A5)        ships initial x,y & speed
  434.     move.w    #80,ypos(a5)
  435.     move.w    #2,ship.speed(a5)
  436.     move.w    #1,mult.number(a5)
  437.     move.l    #ship1.2,shipaddress(a5) setup address of initial ship
  438.  
  439.     lea    copperlist(pc),a1
  440.     lea    rasters(a5),a0
  441.     move.w    (a0),2(a1)        copy the plane adresses into the
  442.     move.w    2(a0),6(a1)        copperlist
  443.     move.w    4(a0),10(a1)
  444.     move.w    6(a0),14(a1)
  445.     move.w    8(a0),18(a1)
  446.     move.w    10(a0),22(a1)
  447.     move.w    12(a0),26(a1)
  448.     move.w    14(a0),30(a1)
  449.     move.w    16(a0),34(a1)
  450.     move.w    18(a0),38(a1)
  451.     move.w    20(a0),42(a1)
  452.     move.w    22(a0),46(a1)
  453.     addq.w    #4,6(a1)        skip the hidden words in the
  454.     addq.w    #4,14(a1)        background
  455.     addq.w    #4,22(a1)
  456.     lea    scroll.value(pc),a0
  457.     move.w    #$ff,2(a0)
  458.  
  459.     move.l    #panel+32,d0        put the address of the panel
  460.     lea    rastersplit2(pc),a1    graphics into the copper
  461.     moveq    #3,d1            the panel is 4 planes
  462. setup1    move.w    d0,6(a1)
  463.     swap    d0
  464.     move.w    d0,2(a1)
  465.     swap    d0
  466.     add.l    #1408,d0        panel size is 352x32 (1408 bytes
  467.     addq    #8,a1            per plane)
  468.     dbf    d1,setup1
  469.  
  470.     lea    level.colours(pc),a0    copy the level colours into the
  471.     lea    colours(pc),a1        copperlist
  472.     moveq    #31,d0
  473. .copy    move.w    (a0)+,2(a1)
  474.     addq    #4,a1
  475.     dbf    d0,.copy
  476.  
  477.     lea    panel.colours(pc),a0    copy the panel colours into the
  478.     lea    colours2(pc),a1        copperlist
  479.     moveq    #15,d0
  480. .copy2    move.w    (a0)+,2(a1)
  481.     addq    #4,a1
  482.     dbf    d0,.copy2
  483.  
  484.     bsr    ship.to.copper        setup the hardware sprite pointers
  485.  
  486.     bsr    clear.screen
  487.     bsr    buildbackgnd        and draw the background
  488.     bsr    setup.mouse
  489.  
  490.     IFNE    FullFirepower
  491.     st.b    mult1.on(a5)
  492.     st.b    mult2.on(a5)
  493.     st.b    canons.on(a5)
  494.     st.b    lasers.on(A5)
  495.     move.w    #2,ship.speed(A5)
  496.     move.b    #3,ship.status(a5)    
  497.     bsr    change.ship
  498.     ENDC
  499.     rts
  500.  
  501.  
  502. clear.screen
  503.     move.l    rasters(a5),a0        clear all the screen memory
  504.     move.w    #MemNeeded/4-1,d0
  505. clear.scr1
  506.     clr.l    (a0)+
  507.     dbf    d0,clear.scr1
  508.     rts
  509.  
  510. **************************************************************************
  511.  
  512. moveship
  513.     bsr    joy            read joystick & mouse
  514.     tst.w    ypos(a5)        upper y limit of 0
  515.     bge    up.ok
  516.     clr.w    d0            reset up flag if not allowed
  517.     clr.w    yvector(a5)        and no y movement
  518. up.ok    cmp.w    #150,ypos(a5)        maximum y value is 150
  519.     ble    down.ok
  520.     clr.w    d1            if at max signal down no more
  521.     clr.w    yvector(a5)
  522. down.ok    tst.w    xpos(a5)        minimum x position is 0
  523.     bge    left.ok
  524.     clr.w    d3
  525.     clr.w    xvector(a5)
  526. left.ok    cmp.w    #266,xpos(a5)        maximum x position is 266
  527.     ble    right.ok
  528.     clr.w    d2
  529.     clr.w    xvector(a5)
  530. right.ok
  531.  
  532.     move.w    ship.speed(a5),d4    d4 = ship speed
  533.     move.w    d4,d5            d5 = -ve ship speed
  534.     neg.w    d5                
  535.     clr.w    up.down(a5)        make ship untilt
  536.     move.w    yvector(a5),d7        change the y vector first
  537. up    tst.w    d0            are we going up?
  538.     beq    down            no, so check down    
  539.     move.w    #-560,up.down(a5)    yes, so tilt ship up (anims 560 bytes apart)
  540.     cmp.w    d7,d5            are we at max y speed
  541.     beq    right            yes, so go and check x movement
  542.     subq.w    #1,d7            no, so decrease the vector
  543.     bra    right
  544. down    tst.w    d1            are we going down?
  545.     beq    right            no, so check right
  546.     move.w    #560,up.down(a5)    yes, so tilt the ship down
  547.     cmp.w    d7,d4            are we at max y speed
  548.     beq    right            yes, so check x movement
  549.     addq.w    #1,d7            no, so increase the y vector
  550. right    move.w    d7,yvector(a5)        store the new y vector
  551.     move.w    xvector(a5),d7
  552.     clr.w    d6            now do the x vector which is
  553.     tst.w    d2            virtually identical to the y above
  554.     beq    left
  555.     moveq    #1,d6
  556.     cmp.w    d7,d4
  557.     beq    add.vectors
  558.     addq    #1,d7
  559.     bra    add.vectors
  560. left    tst.w    d3
  561.     beq    add.vectors
  562.     moveq    #-1,d6
  563.     cmp.w    d7,d5
  564.     beq    add.vectors
  565.     subq    #1,d7
  566. add.vectors
  567.     move.w    d7,xvector(a5)
  568.  
  569.     or.w    d2,d3            if we have moved left or right we
  570.     bne    checky            may have to alter the animation
  571.     move.w    #4,mult.delay(a5)    of the multiples
  572.  
  573.     moveq    #1,d7            if the ship is not being moved but
  574.     tst.w    xvector(a5)        still has some inertia then decrease
  575.     beq    checky            the x & y vectors until they hit 0
  576.     bmi    xto0
  577.     neg.w    d7
  578. xto0    add.w    d7,xvector(a5)
  579. checky    or.w    d0,d1
  580.     bne    add.vectors2
  581.     moveq    #1,d7
  582.     tst.w    yvector(a5)
  583.     beq    add.vectors2
  584.     bmi    yto0
  585.     neg.w    d7
  586. yto0    add.w    d7,yvector(a5)
  587.  
  588. add.vectors2
  589.     move.w    xpos(a5),d4        finally add the new vectors to
  590.     move.w    ypos(a5),d5        the x & y coordinates
  591.     add.w    xvector(a5),d4
  592.     add.w    yvector(a5),d5
  593.     move.w    d4,xpos(a5)
  594.     move.w    d5,ypos(a5)
  595.     bsr    xytosprite        convert the xy coords into
  596.     move.l    shipaddress(a5),a0    hardware sprite format
  597.     add.w    up.down(a5),a0        add the up/down offset
  598.  
  599.  
  600.     * now set up the four hardware sprite control words
  601.  
  602.     move.l    d0,(a0)            ship 1.1 (rear end)
  603.     bset    #7,d0
  604.     move.l    d0,184(a0)        ship 1.2 with attach bit set
  605.     add.l    #$0b080000,d0        add 11 to vstart & 16 to hstart
  606.     bclr    #7,d0            reset attach bit
  607.     sub.w    #$0b00,d0        vstop is 11 less
  608.     move.l    d0,2*184(a0)        ship 1.3 (front)
  609.     bset    #7,d0            set attach
  610.     move.l    d0,2*184+96(a0)        ship 1.4
  611.     bsr    ship.to.copper        put the address of the current
  612.     subq.w    #1,mult.delay(a5)    ship in the copper
  613.     bne    same.outrider        and finally work out which multiple 
  614.     move.w    #4,mult.delay(a5)    to display
  615.     add.w    d6,mult.number(a5)    outriders must be between
  616.     bne    max.mult        1 & 5
  617.     move.w    #1,mult.number(a5)
  618. max.mult
  619.     cmp.w    #6,mult.number(a5)
  620.     bne    same.outrider
  621.     move.w    #5,mult.number(a5)
  622. same.outrider
  623.     bsr    draw.outrider        draw the multiple into the sprite
  624.     rts
  625.  
  626. **************************************************************************
  627.  
  628. xytosprite
  629. *    d4 = x coordinate
  630. *    d5 = y coordinate
  631. *    returns d0.l as the control words
  632.  
  633.     clr.l    d0            return longword in do
  634.     add.w    #44-11,d5        hardware offset vertical
  635.     lsl.w    #8,d5            into bits 8-15
  636.     add.w    #128,d4            horizontal offset
  637.     lsr.w    #1,d4            /2 low bit into extend
  638.     or.w    d5,d4            X intact
  639.     move.w    d4,d0            X still intact
  640.     swap    d0            ditto
  641.     roxl.w    #1,d0            get low bit of hstart into bit 0
  642.     add.w    #$2c00,d5        calcualate vstop (+44 lines)
  643.     or.w    d5,d0            low word set up
  644.     rts
  645.  
  646. **************************************************************************
  647.  
  648. draw.outrider
  649.     move.w    mult.number(a5),d0    get the animation number
  650.     tst.b    mult1.on(a5)        for the multiple
  651.     bne    mult1ok
  652.     clr.w    d0
  653. mult1ok
  654.     lea    outriders,a0        base address of outriders
  655.     mulu    #44,d0            44 bytes per plane for pair
  656.     add.w    d0,a0
  657.     move.l    a0,a1            a0 = plane 1
  658.     add.w    #264,a1            a1 = plane 2
  659.     move.l    shipaddress(a5),a2    current ship address
  660.     add.w    up.down(a5),a2
  661.     addq    #4,a2            get past sprite header
  662.     movem.l    a0-a2,-(sp)
  663.     moveq    #10,d7            11 lines high
  664. out1    move.w    (a0)+,(a2)+
  665.     move.w    (a1)+,(a2)+
  666.     dbf    d7,out1
  667.     tst.b    mult2.on(a5)
  668.     bne    mult2ok
  669.     lea    outriders,a0        if mult 2 not on then
  670.     move.l    a0,a1            point the data to zeroes
  671. mult2ok
  672.     add.w    #22*2*2,a2        pass the ship graphics
  673.     moveq    #10,d7            and draw the bottom one
  674. out2    move.w    (a0)+,(a2)+
  675.     move.w    (a1)+,(a2)+
  676.     dbf    d7,out2            planes 1 & 2 done
  677.  
  678.     movem.l    (sp)+,a0-a2        get back pointers
  679.     add.w    #528,a0            a0 = plane 3
  680.     add.w    #528,a1            a1 = plane 4
  681.     add.w    #44*4+8,a2        next sprite
  682.     moveq    #10,d7            11 lines high
  683. out3    move.w    (a0)+,(a2)+
  684.     move.w    (a1)+,(a2)+
  685.     dbf    d7,out3
  686.     tst.b    mult2.on(a5)
  687.     bne    mult3ok
  688.     lea    outriders,a0        if mult 2 not on then
  689.     move.l    a0,a1            point the data to zeroes
  690. mult3ok
  691.     add.w    #22*2*2,a2        pass the ship graphics
  692.     moveq    #10,d7            and draw the bottom one
  693. out4    move.w    (a0)+,(a2)+
  694.     move.w    (a1)+,(a2)+
  695.     dbf    d7,out4            planes 3 & 4 done
  696.     rts
  697.  
  698.  
  699. **************************************************************************
  700.  
  701. setup.mouse
  702.     move.w    joy0dat(a6),d4        read the mouse x,y position so
  703.     move.w    d4,-(sp)
  704.     and.w    #$ff,d4            the ship doesnt jump when we
  705.     move.w    d4,oldmousex(a5)    start
  706.     move.w    (sp)+,d4
  707.     lsr.w    #8,d4
  708.     move.w    d4,oldmousey(a5)
  709.     rts
  710.  
  711. joy    move.w    #$0100,d0        setup the mask for each bit in
  712.     move.w    #$0001,d1        the joystick register
  713.     move.w    #$0002,d2        the routine returns left/right
  714.     move.w    #$0200,d3        /up/down in d0..d3
  715.     move.w    joy1dat(a6),d4        if the corresponding data register
  716.     and.w    d4,d0            is not = 0 then the joystick
  717.     and.w    d4,d1            had been pressed in that direction
  718.     and.w    d4,d2
  719.     and.w    d4,d3
  720.     lsl.w    #1,d0
  721.     lsl.w    #1,d1
  722.     eor.w    d2,d1
  723.     eor.w    d3,d0
  724.  
  725.     move.w    joy0dat(a6),d4        read the mouse counters, if a move
  726.     move.w    d4,-(sp)        has been detected then set the
  727.     and.w    #$ff,d4            appropiate joystick registers
  728.     sub.w    oldmousex(a5),d4    to mimick a joystick move
  729.     beq    noxmove
  730.     bmi    leftmove        this is not a proper proportional
  731.     moveq    #1,d2            read but a simple up/dowm/left/right
  732.     bra    noxmove            check
  733. leftmove
  734.     moveq    #1,d3
  735. noxmove    move.w    (sp),d4
  736.     lsr.w    #8,d4
  737.     sub.w    oldmousey(a5),d4
  738.     beq    joyend
  739.     bmi    upmove
  740.     moveq    #1,d1
  741.     bra    joyend
  742. upmove    moveq    #1,d0
  743. joyend    move.w    (sp),d4
  744.     and.w    #$ff,d4
  745.     move.w    d4,oldmousex(a5)    save the mouse values for comparison
  746.     move.w    (sp)+,d4        next time around
  747.     lsr.w    #8,d4
  748.     move.w    d4,oldmousey(a5)
  749.     rts
  750.  
  751. **************************************************************************
  752.  
  753. ship.to.copper
  754.     move.l    shipaddress(a5),a1    get the current ship address
  755.     add.w    up.down(a5),a1        and update the four sprite
  756.     move.l    a1,d0            pointers in the copperlist
  757.     move.l    a1,d1            
  758.     move.l    a1,d2
  759.     move.l    a1,d3    
  760.     add.w    #184,d1            work out the address of each        
  761.     add.w    #184*2,d2        hardware sprite
  762.     add.w    #184*2+96,d3
  763.     lea    sprite(pc),a0
  764.     move.w    d0,6(a0)
  765.     swap    d0
  766.     move.w    d0,2(a0)
  767.     move.w    d1,14(a0)
  768.     swap    d1
  769.     move.w    d1,10(a0)
  770.     move.w    d2,22(a0)
  771.     swap    d2
  772.     move.w    d2,18(a0)
  773.     move.w    d3,30(a0)
  774.     swap    d3
  775.     move.w    d3,26(a0)
  776.     rts
  777.  
  778. **************************************************************************
  779.  
  780. change.ship
  781.     clr.w    d0
  782.     move.b    ship.status(a5),d0    1 = canons, 2 = lasers, 3 = both
  783.     lea    ship1.2(pc),a0
  784.     mulu    #1680,d0        968 bytes for the four sprites
  785.     add.l    d0,a0            per ship
  786.     move.l    a0,shipaddress(a5)    store the ship address
  787.     rts
  788.  
  789. **************************************************************************
  790.  
  791.  
  792. clist        DC.W    $0A01,$FF00
  793. copperlist    DC.W    bplpt+0,$0000,bplpt+2,$0000
  794.         DC.W    bplpt+8,$0000,bplpt+10,$0000
  795.         DC.W    bplpt+16,$0000,bplpt+18,$0000
  796.         DC.W    bplpt+4,$0000,bplpt+6,$0000
  797.         DC.W    bplpt+12,$0000,bplpt+14,$0000
  798.         DC.W    bplpt+20,$0000,bplpt+22,$0000
  799.         DC.W    bplcon0,$6600
  800. scroll.value    DC.W    bplcon1,$00FF,bpl1mod,$0036
  801.         DC.W    bpl2mod,$002E,bplcon2,$0044
  802.         DC.W    ddfstrt,$0028,ddfstop,$00D8
  803.         DC.W    diwstrt,$1F78,diwstop,$FFC6
  804. colours        DC.W    color+0,$0000,color+2,$0000
  805.         DC.W    color+4,$0000,color+6,$0000
  806.         DC.W    color+8,$0000,color+10,$0000
  807.         DC.W    color+12,$0000,color+14,$0000
  808.         DC.W    color+16,$0000,color+18,$0000
  809.         DC.W    color+20,$0000,color+22,$0000
  810.         DC.W    color+24,$0000,color+26,$0000
  811.         DC.W    color+28,$0000,color+30,$0000
  812.         DC.W    color+32,$0000,color+34,$0000
  813.         DC.W    color+36,$0000,color+38,$0000
  814.         DC.W    color+40,$0000,color+42,$0000
  815.         DC.W    color+44,$0000,color+46,$0000
  816.         DC.W    color+48,$0000,color+50,$0000
  817.         DC.W    color+52,$0000,color+54,$0000
  818.         DC.W    color+56,$0000,color+58,$0000
  819.         DC.W    color+60,$0000,color+62,$0000
  820.  
  821. sprite        DC.W    sprpt+0,$0000,sprpt+2,$0000
  822.         DC.W    sprpt+4,$0000,sprpt+6,$0000
  823.         DC.W    sprpt+8,$0000,sprpt+10,$0000
  824.         DC.W    sprpt+12,$0000,sprpt+14,$0000
  825.         DC.W    sprpt+16,$0000,sprpt+18,$0000
  826.         DC.W    sprpt+20,$0000,sprpt+22,$0000
  827.         DC.W    sprpt+24,$0000,sprpt+26,$0000
  828.         DC.W    sprpt+28,$0000,sprpt+30,$0000
  829.  
  830.         DC.W    $DF01,$FF00
  831.         DC.W    bplcon1,$0000,bplcon0,$4200,ddfstrt,$0030
  832. rastersplit2    DC.W    bplpt+0,$0000,bplpt+2,$0000
  833.         DC.W    bplpt+4,$0000,bplpt+6,$0000
  834.         DC.W    bplpt+8,$0000,bplpt+10,$0000
  835.         DC.W    bplpt+12,$0000,bplpt+14,$0000
  836. colours2    DC.W    color+20,$0000,color+30,$0000
  837.         DC.W    color+2,$0000,color+4,$0000
  838.         DC.W    color+6,$0000,color+8,$0000
  839.         DC.W    color+10,$0000,color+12,$0000
  840.         DC.W    color+14,$0000,color+16,$0000
  841.         DC.W    color+18,$0000,color+22,$0000
  842.         DC.W    color+24,$0000,color+26,$0000
  843.         DC.W    color+28,$0000,color+0,$0000
  844.         DC.W    bpl1mod,$0000,bpl2mod,$0000
  845.         DC.W    $DF01,$FF00,intreq,$8010
  846.         DC.W    $FFFF,$FFFE
  847.  
  848.  
  849. panel.colours    DC.W    $0600,$0333,$0fb3,$0d00,$0b00,$0720,$0fc2,$0c90
  850.         DC.W    $0a40,$0eb0,$0eca,$0456,$0577,$0252,$0444,$0000
  851.  
  852.     rsreset
  853. screen.num    RS.B    1    
  854. vcount        RS.B    1    vertical blank counter
  855. mult1.on    RS.B    1    byte set if a multiple is attached to ship
  856. mult2.on    RS.B    1    same for another multiple (2 max)
  857. canons.on    RS.B    1    bytes are set to signify what weapons
  858. lasers.on    RS.B    1    are attached
  859. ship.status    RS.B    1    values to indicate which ship to draw
  860.  
  861. ship.speed    RS.W    1    speed in pixels
  862. xpos        RS.W    1    ship x position
  863. ypos        RS.W    1    ship y position
  864. mult.number    RS.W    1    multiple animation number
  865. mult.delay    RS.W    1    multiple animation delay
  866. xvector        RS.W    1    inertia vectors for the ship
  867. yvector        RS.W    1
  868. oldmousex    RS.W    1    store the old mouse values to reference
  869. oldmousey    RS.W    1    the new ones to
  870. up.down        RS.W    1    this holds the graphic offset for a ship tilt
  871.  
  872. pf1count    RS.W    1    number of background words to scroll
  873. pf2count    RS.W    1    number of foreground words to scroll
  874. pf1scroll    RS.W    1    pixel scroll value (0-15) background
  875. pf2scroll    RS.W    1    pixel scroll value (0-15) foreground
  876. pf1scroll2    RS.W    1
  877. pf2offset    RS.W    1
  878. screenend    RS.W    1
  879. level.end    RS.W    1
  880. level.number    RS.W    1
  881.  
  882. fgndpointer    RS.L    1    foreground map pointer
  883. displayraster    RS.L    6    holds the addresses of the planes
  884. rasters     RS.L    9    updated plane addresses
  885. shipaddress    RS.L    1    ship animation address
  886.  
  887. vars.length    RS.B    0
  888. variables    DS.B    vars.length
  889.  
  890. backgroundtable    DC.W    $0123,$0123,$0123,$0123,$0123,$0123 background
  891.         DC.W    $4567,$4567,$4567,$4567,$4567,$4567 map
  892.         DC.W    $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
  893.         DC.W    $0123,$0123,$0123,$0123,$0123,$0123
  894.         DC.W    $4567,$4567,$4567,$4567,$4567,$4567
  895.         DC.W    $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
  896.         DC.W    $0123,$0123,$0123,$0123,$0123,$0123
  897.         DC.W    $4567,$4567,$4567,$4567,$4567,$4567
  898.         DC.W    $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
  899.         DC.W    $0123,$0123,$0123,$0123,$0123,$0123
  900.         DC.W    $4567,$4567,$4567,$4567,$4567,$4567
  901.         DC.W    $89AB,$89AB,$89AB,$89AB,$89AB,$89AB
  902.  
  903. backgrounds    DC.W  $1430,$0C30,$0C10,$0413,$8403,$4442,$2142,$3120
  904.         DC.W  $3110,$2810,$141C,$1417,$140B,$0C71,$0A00,$DC08
  905.         DC.W  $8A08,$9208,$0229,$8208,$4244,$2221,$12A1,$0891
  906.         DC.W  $0888,$148A,$0A03,$2A48,$8A44,$9208,$8524,$2204
  907.  
  908.         DC.W  $0210,$0230,$1118,$0118,$8128,$414C,$314C,$10CA
  909.         DC.W  $1005,$1013,$5103,$31C3,$5023,$D011,$3018,$6304
  910.         DC.W  $0129,$0908,$0884,$0884,$4294,$22A2,$08A2,$0825
  911.         DC.W  $0842,$0908,$2880,$C824,$2890,$2808,$0904,$1092
  912.  
  913.         DC.W  $0300,$4220,$0461,$0451,$0850,$08C8,$38C8,$1848
  914.         DC.W  $0848,$0848,$0848,$08C8,$0148,$1050,$E060,$4041
  915.         DC.W  $2084,$2110,$2210,$0228,$0429,$1424,$0424,$0424
  916.         DC.W  $8424,$8424,$8424,$8424,$80A4,$8828,$1011,$2420
  917.  
  918.         DC.W  $1430,$0C08,$0800,$0413,$8083,$4442,$2242,$2120
  919.         DC.W  $2110,$2810,$040C,$1487,$104B,$0C71,$0A10,$D908
  920.         DC.W  $8A08,$9000,$042D,$8008,$4244,$2221,$1121,$0091
  921.         DC.W  $0888,$048A,$0A03,$2240,$8220,$9208,$8124,$2004
  922.  
  923.         DC.W  $7028,$6218,$8218,$C208,$C210,$C210,$6420,$2420
  924.         DC.W  $4820,$4820,$8843,$0882,$108C,$2118,$2220,$4421
  925.         DC.W  $0914,$1104,$4104,$2504,$2508,$2508,$9250,$1250
  926.         DC.W  $2450,$2410,$4420,$8441,$0840,$1080,$1110,$A210
  927.  
  928.         DC.W  $C60C,$C60A,$4609,$2209,$A201,$A223,$9011,$901F
  929.         DC.W  $900C,$8C18,$0620,$060F,$0213,$0404,$1405,$1419
  930.         DC.W  $2102,$2105,$2104,$5104,$5124,$5110,$4908,$4900
  931.         DC.W  $4902,$4204,$8912,$0900,$2508,$0212,$4A02,$EA04
  932.  
  933.         DC.W  $0080,$0100,$0110,$0918,$0A14,$0A33,$8A31,$0621
  934.         DC.W  $0220,$8204,$8204,$860D,$860A,$8A0C,$0108,$0101
  935.         DC.W  $4940,$0888,$8888,$8484,$852A,$8508,$4508,$8110
  936.         DC.W  $4911,$4902,$490A,$4102,$4905,$4502,$8084,$9088
  937.  
  938.         DC.W  $7028,$4318,$8298,$C248,$8250,$C210,$6120,$20A0
  939.         DC.W  $5820,$4820,$8813,$188A,$108C,$2100,$2220,$4421
  940.         DC.W  $0914,$1004,$4144,$2504,$4528,$2528,$9290,$1010
  941.         DC.W  $2010,$2410,$4428,$8405,$0842,$1080,$1100,$A210
  942.  
  943.         DC.W  $8820,$0440,$0204,$1202,$8221,$8220,$8300,$8410
  944.         DC.W  $C080,$0180,$20C0,$6040,$7060,$31A1,$2820,$2820
  945.         DC.W  $4410,$8A24,$0122,$8921,$4910,$4110,$4090,$4208
  946.         DC.W  $2448,$8048,$1020,$1220,$0910,$0850,$9492,$1412
  947.  
  948.         DC.W  $CE02,$4A02,$5402,$0442,$0844,$9048,$E148,$4150
  949.         DC.W  $23A0,$31C4,$3185,$3842,$2820,$11A0,$23A0,$6322
  950.         DC.W  $0101,$2501,$2A01,$9221,$9422,$68A4,$10A4,$A0A8
  951.         DC.W  $1050,$0822,$0842,$04A1,$1412,$8850,$5051,$1091
  952.  
  953.         DC.W  $3100,$11C0,$10C1,$10E1,$4862,$8850,$9850,$88F0
  954.         DC.W  $E830,$7031,$0028,$8248,$4088,$4018,$2018,$3018
  955.         DC.W  $0881,$0821,$0820,$0810,$2411,$5429,$44A9,$4408
  956.         DC.W  $0408,$0808,$8114,$4124,$2144,$2104,$1224,$0844
  957.  
  958.         DC.W  $C820,$4440,$2204,$1002,$8225,$8224,$8308,$8418
  959.         DC.W  $C980,$1188,$20C4,$6040,$6260,$2121,$2820,$2820
  960.         DC.W  $0410,$AA24,$1122,$8921,$4912,$0110,$4094,$4380
  961.         DC.W  $2448,$8844,$1020,$1220,$0110,$0850,$9492,$1412
  962.  
  963. level.colours
  964.         DC.W    $0332,$0055,$0543,$0000,$0000,$0000,$0000,$0000
  965.         DC.W    $0000,$0F55,$0B05,$0700,$08A7,$0182,$0065,$0055
  966.         DC.W    $0000,$0FF6,$0000,$0FD0,$0A00,$0BDF,$06AF,$004F
  967.         DC.W    $0FFF,$0CDD,$0ABB,$0798,$0587,$0465,$0243,$0E32
  968.  
  969.  
  970. *******************************************************************************
  971. *******************************************************************************
  972.  
  973. finished
  974.     bsr    FreeSystem
  975.  
  976. MemError    move.l    _SysBase,a6
  977.     move.l    MemBase,a1
  978.     move.l    #MemNeeded,d0        free the memory we took
  979.     jsr    _LVOFreeMem(a6)
  980.     move.l    GraphicsBase,a1    
  981.     jsr    _LVOCloseLibrary(a6)
  982.     move.l    DOSBase,a1        finally close the 
  983.     jsr    _LVOCloseLibrary(a6)    libraries
  984.     clr.l    d0
  985.     rts
  986.  
  987. *******************************************************************************
  988.  
  989. TakeSystem
  990.     move.w    intenar(a6),SystemInts        save system interupts
  991.     move.w    dmaconr(a6),SystemDMA        and DMA settings
  992.     move.w    #$7fff,intena(a6)        kill everything!
  993.     move.w    #$7fff,dmacon(a6)
  994.     move.b    #%01111111,ICRA            kill keyboard
  995.     move.l    $68,Level2Vector        save these interrupt vectors
  996.     move.l    $6c,Level3Vector        as we will use our own 
  997.     rts                    keyboard & vblank routines
  998.  
  999. FreeSystem
  1000.     move.l    Level2Vector,$68    restore the system vectors
  1001.     move.l    Level3Vector,$6c        and interrupts and DMA
  1002.     move.l    GraphicsBase,a1            and replace the system
  1003.     move.l    SystemCopper1(a1),Hardware+cop1lc    copper list
  1004.     move.l    SystemCopper2(a1),Hardware+cop2lc
  1005.     move.w    SystemInts,d0
  1006.     or.w    #$c000,d0
  1007.     move.w    d0,intena(a6)
  1008.     move.w    SystemDMA,d0
  1009.     or.w    #$8100,d0
  1010.     move.w    d0,dmacon(a6)
  1011.     move.b    #%10011011,ICRA    keyboard etc back on
  1012.     rts
  1013.  
  1014. *******************************************************************************
  1015.  
  1016. Level2Vector        dc.l    0
  1017. Level3Vector        dc.l    0
  1018. SystemInts        dc.w    0
  1019. SystemDMA        dc.w    0
  1020. MemBase            dc.l    0
  1021. DOSBase            dc.l    0
  1022. GraphicsBase        dc.l    0
  1023.  
  1024.     even
  1025. GraphicsName    dc.b    'graphics.library',0
  1026.     even
  1027. DOSName        dc.b    'dos.library',0
  1028.  
  1029. *******************************************************************************
  1030.  
  1031. shipbase    include    ships.s
  1032. graphics    incbin    foregrounds
  1033. map        incbin    map
  1034. panel        incbin    panel
  1035.  
  1036.  
  1037.     end
  1038.  
  1039.